package net.tycmc.cty.ctyms.timejob.function.monitore;

import java.io.BufferedReader;
import java.io.IOException;
//import java.io.InputStream;
import java.io.InputStreamReader;
//import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
//import java.net.URLConnection;
//import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
//import java.util.HashMap;
import java.util.Map;

//import javax.xml.parsers.ParserConfigurationException;
//import javax.xml.parsers.SAXParser;
//import javax.xml.parsers.SAXParserFactory;

import net.tycmc.bulb.common.dao.BaseDAO;
import net.tycmc.bulb.common.datasource.ProxoolDataSource;
import net.tycmc.bulb.common.util.MapGetter;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
//import org.xml.sax.Attributes;
//import org.xml.sax.SAXException;
//import org.xml.sax.helpers.DefaultHandler;

import com.tycmc.functions.util.DynamicReadConfig;
import com.tycmc.functions.util.StringUtil;

public class CheckSelfAndReport {
	private static Logger logger = Logger.getLogger("CheckSelfAndReport");
	private String fastFaultInterface;
	private BaseDAO baseDAO;
	private static String proxool = "proxool.test";
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	public CheckSelfAndReport(){
		baseDAO = new BaseDAO();
		ProxoolDataSource connGetter = new ProxoolDataSource();
		connGetter.setProxoolname(proxool);
		baseDAO.setConnGetter(connGetter);
	}
	/**
	 * 自检，目前的逻辑：作业执行业务逻辑前，查询设备视图是否可用，不可用时认为上报信息
	 * @return boolean true:自检通过、或者自检未通过但是正常上报报警
	 **/
	public boolean checkIfFailReport(Map<String,Object> param){
		boolean flag = false;
		if(!this.checkSelfByVView()){
			if(this.reportFastFault(param)){
				flag = true;
			}
		}else{
			flag = true;
		}
		return flag;
	}
	
	/**
	 * 上报紧急接口报警
	 **/
	private boolean reportFastFault(Map<String,Object> param){
		boolean flag = false;
		String jobName = MapGetter.getString(param,"jobName");
		logger.info(this.sdf.format(new Date())+"自检Job"+jobName+"时失败，"+this.getHostMemoryState()+"开始上报紧急报警接口.");
		if(!StringUtil.isValid(this.fastFaultInterface)){
			try {
				this.fastFaultInterface = DynamicReadConfig.getConfigProperty("config.properties", "fastFaultInterface");
			} catch (ConfigurationException e) {
				logger.info("上报紧急报警时，未获取到上报接口。"+e.getMessage());
				return false;
			}
		}
		String tempUrl = this.fastFaultInterface+new SimpleDateFormat("yyyy-MM-dd%20HH:mm:ss").format(new Date())+"/"+jobName+"自检不通过——查询数据库出错，怀疑数据库链接不可用，请重启相应的tomcat或者通知相关人员。";
//		tempUrl = "http://192.168.30.101:11200/Alarm/CenterAlarm/2015-03-04%2018:41:31/自动安装设备自检不通过——查询数据库出错，怀疑数据库链接不可用，请重启相应的tomcat或者通知相关人员。";
		URL url;
		try {
			url = new URL(tempUrl);
			HttpURLConnection httpConn = (HttpURLConnection)url.openConnection();
		    httpConn.setRequestMethod("GET");
		    httpConn.setRequestProperty("Accept", "application/json");
		    httpConn.setConnectTimeout(1000);
		    BufferedReader bufReader = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
	    	StringBuffer strBuf = new StringBuffer();
	    	String output;
	    	while((output=bufReader.readLine())!=null){
	    		strBuf.append(output);
	    	}
	    	String reJson = strBuf.toString();
			if(StringUtil.isValid(reJson)){
				if(reJson.indexOf("1")>-1){
					flag = true;
					logger.info(sdf.format(new Date())+"   "+jobName + "上报紧急报警时，报警接口应答成功！");
				}else{
					logger.info(sdf.format(new Date())+"   "+jobName + "上报紧急报警时，报警接口应答失败！");
				}
			}else{
				logger.info(sdf.format(new Date())+"   "+jobName + "上报紧急报警时，报警接口应答失败！");
			}
		} catch (MalformedURLException e) {
			logger.info(e.getMessage());
		} catch (IOException e1){
			logger.info(e1.getMessage());
		}
		return flag;
	}
	
	/**
	 * 上报紧急接口报警
	 *
	private boolean reportFastFault(Map<String,Object> param){
		boolean flag = false;
		String jobName = MapGetter.getString(param,"jobName");
		logger.info(this.sdf.format(new Date())+"自检Job"+jobName+"时失败，"+this.getHostMemoryState()+"开始上报紧急报警接口.");
		if(!StringUtil.isValid(this.fastFaultInterface)){
			try {
				this.fastFaultInterface = DynamicReadConfig.getConfigProperty("config.properties", "fastFaultInterface");
			} catch (ConfigurationException e) {
				logger.info("上报紧急报警时，未获取到上报接口。"+e.getMessage());
				return false;
			}
		}
		String tempUrl = this.fastFaultInterface+new SimpleDateFormat("yyyy-MM-dd%20HH:mm:ss").format(new Date())+"/"+jobName+"自检不通过——查询数据库出错，怀疑数据库链接不可用，请重启相应的tomcat或者通知相关人员。";
//		tempUrl = "http://192.168.30.101:11200/Alarm/CenterAlarm/2015-03-04%2018:41:31/自动安装设备自检不通过——查询数据库出错，怀疑数据库链接不可用，请重启相应的tomcat或者通知相关人员。";
		URL url;
		try {
			url = new URL(tempUrl);
			URLConnection conn = url.openConnection();
			conn.setConnectTimeout(5000);//超时时间为5秒
			conn.setDoOutput(true);
			conn.setDoInput(true);
			Map<String,Object> map = this.parseXML(conn.getInputStream());
			if(null!=map && !map.isEmpty()){
				if(MapGetter.getString(map, "int").indexOf("1")>-1){
					flag = true;
					logger.info(sdf.format(new Date())+"   "+jobName + "上报紧急报警时，报警接口应答成功！");
				}else{
					logger.info(sdf.format(new Date())+"   "+jobName + "上报紧急报警时，报警接口应答失败！");
				}
			}else{
				logger.info(sdf.format(new Date())+"   "+jobName + "上报紧急报警时，报警接口应答失败！");
			}
		} catch (MalformedURLException e) {
			logger.info(e.getMessage());
		} catch (IOException e1){
			logger.info(e1.getMessage());
		}
		return flag;
	}
	private Map<String, Object> parseXML(InputStream in) {
		SAXParser saxparser;
		ExigenceHandler hbh = new ExigenceHandler();
		try {
			saxparser = SAXParserFactory.newInstance().newSAXParser();
			saxparser.parse(in, hbh);
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return hbh.map;
	
	}
	*/
	/**
	 * 获取当前服务器内存状态
	 **/
	private String getHostMemoryState() {
		long div1 = 1024*1024;
		NumberFormat nf = new NumberFormat();
		double free = nf.div(Runtime.getRuntime().freeMemory(),div1,2);//jvm中未使用的内存
		double total = nf.div(Runtime.getRuntime().totalMemory(),div1,2);//jvm中内存
		double max = nf.div(Runtime.getRuntime().maxMemory(), div1, 2);//jvm可使用的最大内存
		return "服务器内存使用状态：Free memory: "+free+" MB Total memory: "+total+" MB Max memory: "+max+" MB";
	}
	/**
	 * 自检
	 **/
	private boolean checkSelfByVView(){
		boolean flag = false;
		String sql = "select COUNT(1) as counts from V_VehicleInfo";
		Map<String,Object> map = this.baseDAO.execQueryOne(sql, new Object[]{});
		if(null!=map && !map.isEmpty()&&StringUtil.isValid(MapGetter.getString(map,"counts"))){
			if(Integer.parseInt(MapGetter.getString(map,"counts"))>0){
				flag = true;
			}
		}
		return flag;
	}
	private class NumberFormat{
		double div(double v1, double v2, int scale) {
			double result = 0;
			if (scale < 0) {
				throw new IllegalArgumentException(
						"The scale must be a positive integer or zero");
			}
			if (v2 != 0) {
				BigDecimal b1 = new BigDecimal(Double.toString(v1));
				BigDecimal b2 = new BigDecimal(Double.toString(v2));
				result = b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP)
						.doubleValue();
			}
			return result;
		}
	}
	/*
	class ExigenceHandler extends DefaultHandler{
		private String preTag = null;
		Map<String,Object> map = new HashMap<String,Object>();
		@Override
		public void startElement(String uri,String localName,String qName,Attributes attributes) throws SAXException{
			preTag = qName;
		}
		@Override
		public void endElement(String uri,String localName,String qName) throws SAXException{
			preTag = null;
		}
		@Override
		public void characters(char[] ch,int start,int length) throws SAXException{
			if(null != preTag){
				String content = new String(ch,start,length);
				if(preTag.equals("int")){
					map.put("int", content);
				}
			}
		}
	}*/
	
	
}
